iT邦幫忙

2022 iThome 鐵人賽

DAY 11
0
Mobile Development

Android Studio 30天學習紀錄系列 第 11

Android Studio 30天學習紀錄-Day11 Dagger

  • 分享至 

  • xImage
  •  

今天要來講Dagger這個功能,主要透過外部來產生物件,且進行所謂的依賴注入(DI),可有效解決高耦合(依賴)的問題,可有效減少程式上的修改,那麼首先先加入依賴至gradle:

依賴

    //dagger
    implementation 'com.google.dagger:dagger:2.13'
    annotationProcessor "com.google.dagger:dagger-compiler:2.13"

依賴注入

依賴注入(Dependency Injection),又簡稱DI,主要是在創建一個物件時,將他所依賴的對象可透過外部去進行產生,依賴指的是你創建這個物件所需要的零件,比如一台車,他的零件至少會包含引擎及輪胎,那麼也能代表車依賴於引擎和輪胎,而關於依賴注入也分成了三種模式:

  • Constructor(建構元注入)
class UserData{
    private String account;
    private String password;
    //建構元account、password
    public UserData(String account,String password){
        this.account=account;
        this.password=password;
    }
}
  • Setter(設值注入)
class UserData{
    private String account;
    private String password;
    
    public String getAccount() {
        return account;
    }

    public void setAccount(String account) {
        this.account = account;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}
  • Interface(介面注入)
class UserData implements UserInterface{
    @Override
    public void setUser(String account, String password) {

    }
}

interface UserInterface{
    void setUser(String account, String password);
}

接著要來提有關於Dagger會用到的四大Annotation:

  • Module(包含許多的依賴項-Provides,較常標註model、repository上)
  • Provides(提供依賴)
  • Component(綁module使class可以進行注入)
  • Inject(標記這個物件由外部設定,從Component綁的Module取得對應的Provides)

Module

透過@Named這個annotation能取得對應的資料,操作順序是:從class Component去new物件並綁定->進入MainModel的constructor並設值->取得值後透過@Named提供一個新的MainModel物件出來->Inject注入class的物件中。

@Module
public class MainModel {
    private int i;
    private String s;
    public MainModel(String s,int i){
        this.s=s;
        this.i=i;
    }
    @Provides
    MainModel provideModel(@Named("stringS") String s,@Named("intI") int i){
        return new MainModel(s,i);
    }
    @Named("intI")
    @Provides
    public int getI() {
        return i;
    }

    public void setI(int i) {
        this.i = i;
    }
    @Named("stringS")
    @Provides
    public String getS() {
        return s;
    }

    public void setS(String s) {
        this.s = s;
    }
}


Component

@Component(modules = MainModel.class)
public interface MainComponent {
    void inject(MainActivity activity);
}

主程式

在設計完Component後,接著開始設計主程式,建議先進行build(ctrl+f9),這樣才會產生對應的Dagger Component:
https://ithelp.ithome.com.tw/upload/images/20220922/20139259YFKTxbZddi.jpg
接著就開始進行注入,等Component inject完畢後便可開始@Inject MainModel。

public class MainActivity extends AppCompatActivity {
    @Inject
    MainModel model;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //new物件+接module
        DaggerMainComponent.builder().mainModel(new MainModel("Str",0)).build().inject(this);
        Log.d("MainModel","Int:"+model.getI()+"\n"
                +"String:"+model.getS());
        model.setI(10);
        model.setS("Main");
        Log.d("MainModel","Int:"+model.getI()+"\n"
        +"String:"+model.getS());
    }
}

Log結果

https://ithelp.ithome.com.tw/upload/images/20220922/20139259e3aFzq9QVQ.jpg


上一篇
Android Studio 30天學習紀錄-Day10 ViewBinding
下一篇
Android Studio 30天學習紀錄-Day12 Scope
系列文
Android Studio 30天學習紀錄30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言